package cn.lzm.serializer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * @author lzm
 * @Date 2024/7/28
 * @description
 */
public class KryoSerializer implements Serializer {

    /**
     * 实现每个线程都有一个kryo,解决线程安全问题
     * 这里又没有清理threadLocal，所以是否会发生内存泄漏问题？
     * 所以我认为更好的线程安全实现方式是：不使用全局变量，而是每次new一个对象，这样会更加安全一些
     */
//    private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(() -> {
//        Kryo kryo = new Kryo();
//        kryo.setRegistrationRequired(false);
//        return kryo;
//    });

    @Override
    public <T> byte[] serialize(T data) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        getKryo().writeObject(output, data);
        output.close();
        return baos.toByteArray();
    }

    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        Input input = new Input(bais);
        T result = getKryo().readObject(input, clazz);
        input.close();
        return result;
    }

    private static Kryo getKryo() {
        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false);
        return kryo;
    }

}
